package projet.metier;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import javax.swing.JOptionPane;

import java.util.ArrayList;
import java.util.HashMap;

import edu.uci.ics.jung.graph.Graph;

/**
 * Generate graphics for the application.
 * @author Julien
 */
public class GraphGenerator {
	
	public final static String URL = System.getProperty("user.home") + "\\Graphe";
	public static String GRAPH_NAME = "graph";
	public static String GV_NAME = "G";
	public static String COMMAND1 = "sfdp -Tpng \"-o" + URL + "\\";
	public static String COMMAND2 =".png\" \"" + URL + "\\";
	public static String COMMAND3 =".gv\" -Goverlap=prism";
	
	
	/**
	 * Creates a directory named "Graphe" in the home directory of the user if it doesn't already exist.
	 */
	public GraphGenerator(){
		File file = new File(URL);
		if (!file.exists()){
			file.mkdir();
		}
		
	}
	
	/**
	 * Delete all .png files in the selected folder.
	 */
	public void DeletePNGs(){
		File file = new File(URL);
		File[] files = file.listFiles();
	    
	    for (File f : files){
	    	if (f.getName().endsWith(".png")) {
	    		f.delete();
    		}
    	}
	}
	
	/**
	 * Creates a graph from a .net file and then generates a .png representation of it.
	 * @param net - String - File path.
	 * @param graphName - String - Name wanted for the .png file.
	 * @param gvName - String - Name wanted for the .gv file.
	 * @return Graph<String, Integer> created from .net file
	 */
	public Graph<String, Integer> GenerateFromNet(String net, String graphName, String gvName){
		if (graphName != null && graphName != "") {GRAPH_NAME = graphName;}
		if (gvName != null && gvName != "") {GV_NAME = gvName;}
		
		Graph<String, Integer> G = ProjectTools.readNet(net);
		try {
			ProjectTools.writeGV(URL + "\\" + GV_NAME, G, null);
			Runtime.getRuntime().exec(COMMAND1 + GRAPH_NAME + COMMAND2 + GV_NAME + COMMAND3);
		} catch (IOException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(null, "Une erreur est survenue lors de la création du graphe:\n"+e.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);
		}
		return G;
	}
	
	/**
	 * Generates a .gv and .png of the graph with all the shortest path from a source vertex coloured in red.
	 * @param hash - HashMap<String, Object[]> - Most likely the result of DijkstraAlgorithm.Dijkstra().
	 * @param G - Graph - The graph.
	 * @param graphName - String - Name wanted for the .gv file.
	 * @param gvName - String - Name wanted for the .gv file.
	 */
	public void GenerateShortestPath(HashMap<String, Object[]> hash, Graph<String, Integer> G, String graphName, String gvName){
		if (graphName != null && graphName != "") {GRAPH_NAME = graphName;}
		if (gvName != null && gvName != "") {GV_NAME = gvName;}
		
		HashMap<String, Color> colours = new HashMap<>();
		
		for (String vertex : G.getVertices()){
			Object[] o = hash.get(vertex);
			//System.out.println(vertex + " - Distance: " + (int)o[0] + " - Preceded by: " + (String)o[1]);
			if (o[1] != null && !colours.containsKey(G.findEdge(vertex, o[1].toString()))){
				colours.put(G.findEdge(vertex, o[1].toString()).toString(), Color.RED);
			} else if ((int)o[0] == 0) {
				colours.put(vertex, Color.RED);
			}
		}
		
		try {
			ProjectTools.writeGV(GraphGenerator.URL + "\\" + GV_NAME, G, colours);
			Runtime.getRuntime().exec(COMMAND1 + GRAPH_NAME + COMMAND2 + GV_NAME + COMMAND3);
		} catch (IOException e2) {
			e2.printStackTrace();
			JOptionPane.showMessageDialog(null, "Une erreur est survenue lors de la création du graphe:\n"+e2.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);
		}
	}
	
	/**
	 * Generates a .gv and .png of the graph with the three different kinds of places coloured. (Red: event, green: green space, blue: car parks).
	 * @param G - Graph - The graph.
	 * @param event - String - Vertex string corresponding to the event.
	 * @param green - String - Vertex string corresponding to the Green Space.
	 * @param parks - ArrayList<String> - List of vertices corresponding to car parks.
	 * @param graphName - String - Name wanted for the .gv file.
	 * @param gvName - String - Name wanted for the .gv file.

	 */
	public void GeneratePlaces(Graph<String, Integer> G, String event, String green, ArrayList<String> parks, String graphName, String gvName){
		if (graphName != null && graphName != "") {GRAPH_NAME = graphName;}
		if (gvName != null && gvName != "") {GV_NAME = gvName;}
		
		HashMap<String, Color> colours = new HashMap<>();
		
		if (event != null && G.containsVertex(event)) {colours.put(event, Color.RED);}
		if (green != null && G.containsVertex(green)) {colours.put(green, Color.GREEN);}
		if (parks != null){
			for (String vertex : parks){
				if (vertex != null && G.containsVertex(vertex)) {colours.put(vertex, Color.BLUE);}
			}
		}
		try {
			ProjectTools.writeGV(GraphGenerator.URL + "\\" + GV_NAME, G, colours);
			Runtime.getRuntime().exec(COMMAND1 + GRAPH_NAME + COMMAND2 + GV_NAME + COMMAND3);
		} catch (IOException e2) {
			e2.printStackTrace();
			JOptionPane.showMessageDialog(null, "Une erreur est survenue lors de la création du graphe:\n"+e2.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE);
		}
	}
}

